package com.xml.task;

import com.xml.generated.*;

import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.math.BigInteger;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.bind.*;

public class XMLTask {

	public static void testMarshal(){
		/*
		 * Create XML document and marshal it to the "./xml/marshall.xml" file 
		 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
		 * <catalog xmlns="http://com.xml.task/books">
		 *     <books>
		 *         <book id="111">
		 *             <name>Book1Name</name>
		 *             <ISBN>111111</ISBN>
		 *             <price>111 $</price>
		 *             <authors>
		 *                 <name>Author 1</name>
		 *                 <name>Author 2</name>
		 *                 <name>Author 3</name>
		 *             </authors>
		 *             <description>Book1 description</description>
		 *             <publishDate>2014-01-14</publishDate>
		 *         </book>
		 *     </books>
		 * </catalog>
		 */
		
		// Create all objects
		ObjectFactory factory = new ObjectFactory();
		Catalog mCatalog = factory.createCatalog();
		
		BooksType mBooksList = factory.createBooksType();
		BookType mBook1 = factory.createBookType();
		BookAuthorsType mBookAuthors1 = factory.createBookAuthorsType();
		
		try {
			mBook1.setPublishDate(DatatypeFactory.newInstance().newXMLGregorianCalendar("2014-01-14"));
		} catch (DatatypeConfigurationException e){
			System.out.println(e.getMessage());
			e.printStackTrace();
		}
	
		mBook1.setId(new BigInteger("111"));
		mBook1.setName("Book1Name");
		mBook1.setISBN(new BigInteger("111111"));
		mBook1.setPrice("111 $");
		mBook1.setDescription("Book1 description");
				
		mBookAuthors1.getName().add("Author 1");
		mBookAuthors1.getName().add("Author 2");
		mBookAuthors1.getName().add("Author 3");
		
		mBook1.setAuthors(mBookAuthors1);
		mBooksList.getBook().add(mBook1);	
		mCatalog.getBooks().add(mBooksList);
		
		// Marshal objects to the file "./marshall.xml"
		JAXBContext ctx = null;
		try{
			ctx = JAXBContext.newInstance("com.xml.generated");
			Marshaller marshaller = ctx.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

			// Marshal to the File
			marshaller.marshal(mCatalog, new File("./xml/marshall.xml"));
			
			// Marshal to the string
			StringWriter sw = new StringWriter();
			marshaller.marshal(mCatalog, sw);
			String s = sw.toString();
			System.out.println(">>> Marshal to the String");
			System.out.println(s);
						
			// Marshal to the System.out
			System.out.println(">>> Marshal to the System.out");
			marshaller.marshal(mCatalog, System.out);		
			
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}
	
	public static void testUnmarshalFromFile(){
		try {
			// Unmarshal file ./xml/books.xml"
			JAXBContext ctx = null;
			ctx = JAXBContext.newInstance("com.xml.generated");
			Unmarshaller unmarshaller = ctx.createUnmarshaller();

			Catalog unmarshalledCatalog = (Catalog) unmarshaller.unmarshal(new File("./xml/books.xml"));

			// Marshal to the System.out
			System.out.println(">>> unmarshalledCatalog from file to the System.out");
			Marshaller marshaller = ctx.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			marshaller.marshal(unmarshalledCatalog, System.out);

		} catch (JAXBException e) {
			e.printStackTrace();
		}
				
	}
	
	public static void testUnmarshalFromString(){
		try {
			// Unmarshal from String"
			JAXBContext ctx = null;
			ctx = JAXBContext.newInstance("com.xml.generated");
			Unmarshaller unmarshaller = ctx.createUnmarshaller();
			
			String s = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<catalog xmlns=\"http://com.xml.task/books\">" +
"    <books>" +
"        <book id=\"111\">" +
"            <name>Learning JAXB</name>" +
"            <ISBN>123445</ISBN>" +
"            <price>34 $</price>" +
"            <authors>" +
"                <name>Jane Doe</name>" +
"            </authors>" +
"            <description>Step by step instructions for beginners</description>" +
"            <publishDate>2003-01-01</publishDate>" +
"        </book>" +
"        <book id=\"222\">" +
"            <name>Java Webservices today and Beyond</name>" +
"            <ISBN>522965</ISBN>" +
"            <price>29 $</price>" +
"            <authors>" +
"                <name>John Brown</name>" +
"                <name>Peter T.</name>" +
"            </authors>" +
"            <description>Information for users so that they can start using Java Web Services Developer Pack</description>" +
"            <publishDate>2002-11-01</publishDate>" +
"        </book>" +
"    </books>" +
"</catalog>";
			
			Catalog unmarshalledCatalog = (Catalog) unmarshaller.unmarshal((Reader)new StringReader(s));

			// Marshal to the System.out for test
			System.out.println(">>> unmarshalledCatalog from String to the System.out");
			Marshaller marshaller = ctx.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			marshaller.marshal(unmarshalledCatalog, System.out);

		} catch (JAXBException e) {
			e.printStackTrace();
		}
				
	}
	
	public static void testUnmarshalFromClassPathResource(){
		try {
			// Unmarshal from ClassPath Resource"
			JAXBContext ctx = null;
			ctx = JAXBContext.newInstance("com.xml.generated");
			Unmarshaller unmarshaller = ctx.createUnmarshaller();
			
			// InputStream is = XMLTask.class.getClassLoader().getResourceAsStream("testStream.xml");
			
			InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("testStream.xml");
			System.out.println(Thread.currentThread().getContextClassLoader());
			
			Catalog unmarshalledCatalog = (Catalog) unmarshaller.unmarshal(is);
			
			// Marshal to the System.out for test
			System.out.println(">>> unmarshalledCatalog from ClassPath Resource to the System.out");
			Marshaller marshaller = ctx.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			marshaller.marshal(unmarshalledCatalog, System.out);

		} catch (JAXBException e) {
			e.printStackTrace();
		}
				
	}
	
	public static void main(String[] args) {
		// testMarshal();
		// testUnmarshalFromFile();
		// testUnmarshalFromString();
		testUnmarshalFromClassPathResource();
		
	}

}
